package com.cuckoo.cuckoo_app2.utils;


import com.cuckoo.cuckoo_app2.MyApplication;
import com.cuckoo.cuckoo_app2.config.ApiConfig;
import com.cuckoo.cuckoo_app2.dao.User;
import com.google.gson.Gson;

import java.io.IOException;

import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
import okhttp3.FormBody;
import okhttp3.ResponseBody;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;


public class NetworkRequestHelperUtils {

    public static final OkHttpClient client = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS) // 连接超时
            .readTimeout(10, TimeUnit.SECONDS)    // 读取超时
            .writeTimeout(10, TimeUnit.SECONDS)   // 写入超时
            .build();

    public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
    public static final MediaType FORM = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");


    /**
     * 执行GET请求
     *
     * @param url     请求的URL
     * @param headers 请求报头，以键值对的形式
     * @return 响应的字符串表示
     * @throws IOException 如果请求过程中发生IO异常
     */
    public static String get(String url, Map<String, String> headers) throws IOException {
        Request.Builder builder = new Request.Builder().url(url);
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Request request = builder.build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            return response.body().string();
        }
    }


    /**
     * 执行POST请求（JSON格式）
     *
     * @param url     请求的URL
     * @param json    请求体，JSON格式的字符串
     * @param headers 请求报头，以键值对的形式
     * @return 响应的字符串表示
     * @throws IOException 如果请求过程中发生IO异常
     */
    public static String postJson(String url, String json, Map<String, String> headers) throws IOException {
        RequestBody body = RequestBody.create(json, JSON);
        Request.Builder requestBuilder = new Request.Builder()
                .url(url)
                .post(body);
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                requestBuilder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Request request = requestBuilder.build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);

            ResponseBody res = response.body();
            if (res == null) {
                return null;
            }
            return res.string();
        }
    }

    /**
     * 执行POST请求（Form格式）
     *
     * @param url     请求的URL
     * @param form    请求体，Form格式的字符串
     * @param headers 请求报头，以键值对的形式
     * @return 响应的字符串表示
     * @throws IOException 如果请求过程中发生IO异常
     */
    public static String postForm(String url, String form, Map<String, String> headers) throws IOException {
        FormBody.Builder formBuilder = new FormBody.Builder();
        if (form != null) {
            Gson gson = new Gson();
            Map<String, String> map = gson.fromJson(form, Map.class);
            for (Map.Entry<String, String> entry : map.entrySet()) {
                formBuilder.add(entry.getKey(), entry.getValue());
            }
        }

        RequestBody formBody = formBuilder.build();
        Request.Builder requestBuilder = new Request.Builder()
                .url(url)
                .post(formBody);

        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                requestBuilder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Request request = requestBuilder.build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            return response.body().string();
        }
    }

    /**
     * 执行put 请求
     *
     * @param url
     * @param json
     * @param headers
     * @return
     * @throws IOException
     */
    public static String putJson(String url, String json, Map<String, String> headers) throws IOException {
        RequestBody body = RequestBody.create(json, JSON);
        Request.Builder requestBuilder = new Request.Builder()
                .url(url)
                .put(body);
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                requestBuilder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Request request = requestBuilder.build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            return response.body().string();
        }
    }

    /**
     * PUT请求（表单数据，同步）
     *
     * @param url
     * @param params
     * @param headers
     * @return
     * @throws IOException
     */
    public static String putForm(String url, Map<String, String> params, Map<String, String> headers) throws IOException {
        FormBody.Builder formBuilder = new FormBody.Builder();
        if (params != null) {
            for (Map.Entry<String, String> param : params.entrySet()) {
                formBuilder.add(param.getKey(), param.getValue());
            }
        }
        RequestBody formBody = formBuilder.build();

        Request.Builder builder = new Request.Builder().url(url).put(formBody);
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Request request = builder.build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            return response.body().string();
        }
    }

    /**
     * DELETE请求（同步）
     *
     * @param url
     * @param headers
     * @return
     * @throws IOException
     */
    public static String delete(String url, Map<String, String> headers) throws IOException {
        Request.Builder builder = new Request.Builder().url(url).delete();
        if (headers != null) {
            for (Map.Entry<String, String> entry : headers.entrySet()) {
                builder.addHeader(entry.getKey(), entry.getValue());
            }
        }
        Request request = builder.build();
        try (Response response = client.newCall(request).execute()) {
            if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
            return response.body().string();
        }
    }

    /**
     * 获取请求头
     *
     * @return
     */
    public static HashMap<String, String> getHeaders() {
        return getHeaders(null);
    }

    public static HashMap<String, String> getHeaders(Map<String, String> body) {
        User user = MyApplication.getInstances().getUser();

        HashMap<String, String> headers = new HashMap<>();
        headers.put("Content-Type", "application/json");
        headers.put("Accept", "application/json");

        if (body != null) {
            String timestamp = new Date().getTime() + "";
            headers.put(new ApiConfig().SIGN_KEY, SignUtil.getParamsSign(body));
            headers.put("X-TIMESTAMP", timestamp);
        }

        if (user != null && !user.getToken().isEmpty()) {
            headers.put(new ApiConfig().TOKEN_KEY, user.getToken());
        }
        return headers;
    }

    /**
     * map 转为url 参数
     */
    public static String mapToUrlParams(Map<String, String> params) {
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            sb.append(entry.getKey()).append("=").append(entry.getValue()).append("&");
        }
        return sb.toString().substring(0, sb.length() - 1);
    }

}

